package io.github.echarts.model.theme;

import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;

/**
 * 默认值提供者工厂
 * <p>
 * 负责管理和提供各种组件的默认值处理器。
 * 使用单例模式确保全局共享一个工厂实例。
 * 支持通过Java SPI机制自动发现和注册默认值提供者。
 * </p>
 */
public class DefaultValueProviderFactory {
    
    /**
     * 单例实例
     */
    private static final DefaultValueProviderFactory INSTANCE = new DefaultValueProviderFactory();
    
    /**
     * 默认值提供者映射表
     */
    private final Map<Class<?>, DefaultValueProvider<?>> providers = new HashMap<>();
    
    /**
     * 私有构造函数
     * 初始化时自动发现和注册默认值提供者
     */
    private DefaultValueProviderFactory() {
        discoverProviders();
    }
    
    /**
     * 获取工厂单例实例
     * 
     * @return 工厂实例
     */
    public static DefaultValueProviderFactory getInstance() {
        return INSTANCE;
    }
    
    /**
     * 使用Java SPI机制发现并注册默认值提供者
     */
    private void discoverProviders() {
        ServiceLoader<DefaultValueProvider> serviceLoader = ServiceLoader.load(DefaultValueProvider.class);
        for (DefaultValueProvider<?> provider : serviceLoader) {
            registerProvider(provider);
        }
    }
    
    /**
     * 注册默认值提供者
     * 
     * @param provider 要注册的提供者
     */
    public void registerProvider(DefaultValueProvider<?> provider) {
        if (provider != null) {
            Class<?> supportedType = provider.getSupportedType();
            providers.put(supportedType, provider);
        }
    }
    
    /**
     * 获取指定配置类型的默认值提供者
     * 
     * @param <T> 配置类型
     * @param configClass 配置类
     * @return 默认值提供者，如果未找到则返回null
     */
    @SuppressWarnings("unchecked")
    public <T> DefaultValueProvider<T> getProvider(Class<T> configClass) {
        DefaultValueProvider<?> provider = providers.get(configClass);
        
        if (provider == null) {
            // 尝试查找最接近的父类或接口的提供者
            for (Map.Entry<Class<?>, DefaultValueProvider<?>> entry : providers.entrySet()) {
                if (entry.getKey().isAssignableFrom(configClass)) {
                    provider = entry.getValue();
                    break;
                }
            }
        }
        
        return (DefaultValueProvider<T>) provider;
    }
    
    /**
     * 应用默认值到配置对象
     * 
     * @param <T> 配置类型
     * @param config 配置对象
     * @param context 配置上下文
     * @param theme 主题
     */
    public <T> void applyDefaultsAndTheme(T config, io.github.echarts.model.context.ConfigurationContext context, Theme theme) {
        if (config == null) {
            return;
        }
        
        @SuppressWarnings("unchecked")
        Class<T> configClass = (Class<T>) config.getClass();
        DefaultValueProvider<T> provider = getProvider(configClass);
        
        if (provider != null) {
            // 应用默认值
            provider.applyDefaults(config, context);
            
            // 确保配置完整性
            provider.ensureCompleteness(config, context);
            
            // 应用主题
            if (theme != null) {
                provider.applyTheme(config, theme);
            }
        }
    }
} 